package com.zhdl.hardware.motor.huichuan.repository.impl;

import cn.hutool.core.util.HexUtil;
import com.google.common.eventbus.Subscribe;
import com.project.command.faq.event.behavior.BehaviorPerform;
import com.project.command.instruction.strategy.process.data.AfterStrategyParam;
import com.zhdl.common.eventbus.center.EventBusCenter;
import com.zhdl.hardware.motor.huichuan.repository.HcCmdHandleDao;
import com.zhdl.modules.tools.CommonCallback;
import com.zhdl.modules.tools.IntToHexUtil;
import com.zhdl.network.modbusrtu.ModbusRtuRespPkg;
import com.zhdl.network.modbusrtu.dto.ModbusDto;
import com.zhdl.network.modbusrtu.request.WriteSingleKeepRegisterReq;
import com.zhdl.network.strategy.common.ProtocolContext;
import com.zhdl.network.strategy.modbusrtu.ModbusRtuStrategy;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Slf4j
public class HcCmdHandleDaoImpl implements HcCmdHandleDao {

    /**
     * 汇川电机-串口
     */
    public String port;
    /**
     * 通信协议处理
     */
    public ProtocolContext protocolContext;
    /**
     * Callback 回调管理
     */
    public Map<String, CommonCallback<byte[]>> commonCallbackMap = new ConcurrentHashMap<>();

    public HcCmdHandleDaoImpl(String port, BehaviorPerform behaviorPerform) {
        EventBusCenter.getEventBus().register(this);
        protocolContext = new ProtocolContext(new ModbusRtuStrategy(port, behaviorPerform));
        this.port = port;
    }

    @Subscribe
    public void dataReception(AfterStrategyParam event) {

        /* 判断当前串口 */
        if (port.equals(event.getPortKey())) {
            /* 获取电机指令返回的数据 */
            //此处接收串口或网口客户端回应代码,并处理
            List<ModbusDto> list = event.getNewData();
            ModbusDto modbusDto = list.get(0);

            String instruction = event.getInstruction();
            instruction = instruction.replaceAll(" ", "");
            instruction = instruction.toUpperCase();
            for (String cmd : commonCallbackMap.keySet()) {
                String temp = cmd.toUpperCase();
                if (temp.contains(instruction)) {
                    commonCallbackMap.get(cmd).statusCallback(modbusDto.getUnitBuff());
                    commonCallbackMap.remove(cmd);

                }
            }
        }

    }


    /**
     * 汇川电机-电机停止运动
     *
     * @param slaveStationId 从站ID
     */
    @Override
    public void hcMotorStop(String slaveStationId) {
        WriteSingleKeepRegisterReq req = new WriteSingleKeepRegisterReq();
        req.setId(slaveStationId);
        req.setStartAddress("3100");
        req.setWriteValue("0000");
        try {
            byte[] bytes = ModbusRtuRespPkg.WriteSingleKeepRegister06(req);
            protocolContext.sendCmd(HexUtil.encodeHexStr(bytes));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        log.info("电机停止运动");
    }

    /**
     * 汇川电机-电机伺服使能
     *
     * @param slaveStationId 从站ID
     */
    @Override
    public void hcMotorReady(String slaveStationId) {
        WriteSingleKeepRegisterReq req = new WriteSingleKeepRegisterReq();
        req.setId(slaveStationId);
        req.setStartAddress("3100");
        req.setWriteValue("0001");
        try {
            byte[] bytes = ModbusRtuRespPkg.WriteSingleKeepRegister06(req);
            protocolContext.sendCmd(HexUtil.encodeHexStr(bytes));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        log.info("伺服使能 + cmd + 01");
    }

    /**
     * 汇川电机-电机运动使能
     * 伺服使能+多端位置运动使能
     *
     * @param slaveStationId 从站ID
     */
    @Override
    public void hcMotorRun(String slaveStationId) {
        WriteSingleKeepRegisterReq req = new WriteSingleKeepRegisterReq();
        req.setId(slaveStationId);
        req.setStartAddress("3100");
        req.setWriteValue("0011");
        try {
            byte[] bytes = ModbusRtuRespPkg.WriteSingleKeepRegister06(req);
            protocolContext.sendCmd(HexUtil.encodeHexStr(bytes));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        log.info("电机移动 + cmd + 17");
    }

    /**
     * 汇川电机-设置单个参数的值
     * 功能码06，写入单个寄存器
     *
     * @param slaveStationId 从站Id
     * @param address        寄存器地址
     * @param value          写入的值
     */
    @Override
    public void hcSetSingleValue(String slaveStationId, String address, int value) {
        WriteSingleKeepRegisterReq req = new WriteSingleKeepRegisterReq();
        req.setId(slaveStationId);
        req.setStartAddress(address);
        req.setWriteValue(IntToHexUtil.HeightLowRollBack(IntToHexUtil.shortToHex(value)));
        try {
            byte[] bytes = ModbusRtuRespPkg.WriteSingleKeepRegister(req);
            protocolContext.sendCmd(HexUtil.encodeHexStr(bytes));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 汇川电机-读取当前绝对位置
     *
     * @param slaveStationId 从站Id
     * @param address        寄存器地址
     * @param callback       回调函数
     */
    @Override
    public void hcReadLocation(String slaveStationId, String address, CommonCallback<byte[]> callback) {
        WriteSingleKeepRegisterReq req = new WriteSingleKeepRegisterReq();
        req.setId(slaveStationId);
        req.setStartAddress(address);
        req.setWriteValue("0002");
        try {
            byte[] bytes = ModbusRtuRespPkg.ReadSingleKeepRegister(req);
            commonCallbackMap.put(HexUtil.encodeHexStr(bytes), callback);
            protocolContext.sendCmd(HexUtil.encodeHexStr(bytes));
            commonCallbackMap.put(HexUtil.encodeHexStr(bytes), callback);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        log.info("除渣-读取电机状态");
    }

    /**
     * 汇川电机-电机找原点
     *
     * @param slaveStationId 从站Id
     */
    @Override
    public void hcMotorBackOrigin(String slaveStationId) {
        WriteSingleKeepRegisterReq req = new WriteSingleKeepRegisterReq();
        req.setId(slaveStationId);
        req.setStartAddress("3100");
        req.setWriteValue("0021");
        try {
            byte[] bytes = ModbusRtuRespPkg.WriteSingleKeepRegister06(req);
            protocolContext.sendCmd(HexUtil.encodeHexStr(bytes));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        log.info("电机正在找原点.");
    }


    @Override
    public void motorWriteSlagReady(String slaveStationId) {
        WriteSingleKeepRegisterReq req = new WriteSingleKeepRegisterReq();
        req.setId(slaveStationId);
        req.setStartAddress("3100");
        req.setWriteValue("0001");
        try {
            byte[] bytes = ModbusRtuRespPkg.WriteSingleKeepRegister06(req);
            protocolContext.sendCmd(HexUtil.encodeHexStr(bytes));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        log.info("伺服使能 + cmd + 01");

    }

    @Override
    public void motorWriteSlagRun(String slaveStationId) {
        WriteSingleKeepRegisterReq req = new WriteSingleKeepRegisterReq();
        req.setId(slaveStationId);
        req.setStartAddress("3100");
        req.setWriteValue("0011");
        try {
            byte[] bytes = ModbusRtuRespPkg.WriteSingleKeepRegister06(req);
            protocolContext.sendCmd(HexUtil.encodeHexStr(bytes));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        log.info("电机移动 + cmd + 17");
    }

    @Override
    public void motorWriteSlagStop(String slaveStationId) {
        WriteSingleKeepRegisterReq req = new WriteSingleKeepRegisterReq();
        req.setId(slaveStationId);
        req.setStartAddress("3100");
        req.setWriteValue("0000");
        try {
            byte[] bytes = ModbusRtuRespPkg.WriteSingleKeepRegister06(req);
            protocolContext.sendCmd(HexUtil.encodeHexStr(bytes));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        log.info("电机停止运动");
    }

    @Override
    public void motorWriteSlagZero(String slaveStationId) {
        WriteSingleKeepRegisterReq req = new WriteSingleKeepRegisterReq();
        req.setId(slaveStationId);
        req.setStartAddress("3100");
        req.setWriteValue("0021");
        try {
            byte[] bytes = ModbusRtuRespPkg.WriteSingleKeepRegister06(req);
            protocolContext.sendCmd(HexUtil.encodeHexStr(bytes));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        log.info("电机正在找原点.");
    }

    @Override
    public void motorReadSlagLocation(String slaveStationId, String address, CommonCallback<byte[]> callback) {
        WriteSingleKeepRegisterReq req = new WriteSingleKeepRegisterReq();
        req.setId(slaveStationId);
        req.setStartAddress(address);
        req.setWriteValue("0002");
        try {
            byte[] bytes = ModbusRtuRespPkg.ReadSingleKeepRegister(req);
            commonCallbackMap.put(HexUtil.encodeHexStr(bytes), callback);
            protocolContext.sendCmd(HexUtil.encodeHexStr(bytes));
            commonCallbackMap.put(HexUtil.encodeHexStr(bytes), callback);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        log.info("除渣-读取电机状态");
    }

    @Override
    public void setSlagMoveDist(String slaveStationId, String address, int moveDist) {
        WriteSingleKeepRegisterReq req = new WriteSingleKeepRegisterReq();
        req.setId(slaveStationId);
        req.setStartAddress(address);
        req.setWriteValue(IntToHexUtil.HeightLowRollBack(IntToHexUtil.intToHex(moveDist)));
        try {
            byte[] bytes = ModbusRtuRespPkg.WriteMoreKeepRegister(req);
            protocolContext.sendCmd(HexUtil.encodeHexStr(bytes));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        log.info("除渣-设置电机距离");
    }


    @Override
    public void writeSlag06(String slaveStationId, String address, int value) {
        WriteSingleKeepRegisterReq req = new WriteSingleKeepRegisterReq();
        req.setId(slaveStationId);
        req.setStartAddress(address);
        req.setWriteValue(IntToHexUtil.HeightLowRollBack(IntToHexUtil.shortToHex(value)));
        try {
            byte[] bytes = ModbusRtuRespPkg.WriteSingleKeepRegister(req);
            protocolContext.sendCmd(HexUtil.encodeHexStr(bytes));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void readSlagOriginDistance(String slaveStationId) {
        WriteSingleKeepRegisterReq req = new WriteSingleKeepRegisterReq();
        req.setId(slaveStationId);
        req.setStartAddress("0B07");
        req.setWriteValue("0001");
        try {
            protocolContext.sendCmd(HexUtil.encodeHexStr(ModbusRtuRespPkg.ReadSingleKeepRegister(req)));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        req.setStartAddress("0524");
        try {
            protocolContext.sendCmd(HexUtil.encodeHexStr(ModbusRtuRespPkg.ReadSingleKeepRegister(req)));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}
